﻿namespace HuwmanCode

open System
open System.Runtime.CompilerServices

[<AutoOpen>]
[<RequireQualifiedAccess>]
module Fun =
    /// <summary>
    /// Invokes a function and invokes a compensation action should an exception occur.
    /// </summary>
    /// <param name="compensate">The action to invoke should an exception occur.</param>
    /// <param name="f">The function to invoke.</param>
    /// <return>An option value. None if an exception is caught, otherwise Some('T).</return>
    let Try compensate (f:unit -> 'a) = 
        try
            Some(f ())
        with e ->
            compensate e
            None

    /// <summary>
    /// Invokes a function and invokes a compensation action and reraises the exception should an exception occur.
    /// </summary>
    /// <param name="compensate">The action to invoke should an exception occur.</param>
    /// <param name="f">The function to invoke.</param>
    /// <return>The result of calling f ().</return>
    let TryWithRethrow compensate (f:unit -> 'a) =
        try
            f ()
        with e -> 
            compensate e
            reraise()